package com.mcc.system.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mcc.system.mapper.*;
import com.mcc.system.service.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.mcc.common.annotation.DataScope;
import com.mcc.common.constant.UserConstants;
import com.mcc.common.core.domain.entity.SysRole;
import com.mcc.common.core.domain.entity.SysUser;
import com.mcc.common.exception.CustomException;
import com.mcc.common.utils.SecurityUtils;
import com.mcc.common.utils.StringUtils;
import com.mcc.system.domain.SysPost;
import com.mcc.system.domain.SysUserPost;
import com.mcc.system.domain.SysUserRole;

/**
 * 用户 业务层处理
 *
 * @author gxy
 */
@Service
public class SysUserServiceImpl implements ISysUserService {

    private final Logger log = LoggerFactory.getLogger(getClass());

    @Autowired
    private SysUserMapper userMapper;

    @Autowired
    private ISysDeptService deptService;

    @Autowired
    private SysUserRoleMapper userRoleMapper;

    @Autowired
    private SysUserPostMapper userPostMapper;

    @Autowired
    private ISysConfigService configService;

    @Autowired
    private ISysPostService postService;

    @Autowired
    private ISysRoleService roleService;

    /**
     * 根据条件分页查询用户列表
     *
     * @param user 用户信息
     * @return 用户信息集合信息
     */
    @Override
    public List<SysUser> selectUserList(SysUser user) {
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper();
        if (ObjectUtil.isNotEmpty(user)) {
            queryWrapper.like(ObjectUtil.isNotEmpty(user.getUserName()), "user_name", user.getUserName());
            queryWrapper.like(ObjectUtil.isNotEmpty(user.getPhonenumber()), "phonenumber", user.getPhonenumber());
            queryWrapper.eq(ObjectUtil.isNotEmpty(user.getStatus()), "status", user.getStatus());
            queryWrapper.ge(ObjectUtil.isNotEmpty(user.getBeginTime()), "date_format(create_time,'%Y-%m-%d')", user.getBeginTime());
            queryWrapper.le(ObjectUtil.isNotEmpty(user.getEndTime()), "date_format(create_time,'%Y-%m-%d')", user.getEndTime());
            if (ObjectUtil.isNotEmpty(user.getDeptId()) && user.getDeptId() != 0) {
                queryWrapper.and(i -> i.eq("dept_id", user.getDeptId()).or().inSql("dept_id", "select dept_id from sys_dept where find_in_set(" + user.getDeptId() + ",ancestors)"));
            }
        }
        List<SysUser> res = userMapper.selectList(queryWrapper);
        for (int i = 0; i < res.size(); i++) {
            SysUser sysUser = res.get(i);
            sysUser.setDept(deptService.selectDeptById(sysUser.getDeptId()));
        }
        return res;
    }

    /**
     * 通过用户名查询用户
     *
     * @param userName 用户名
     * @return 用户对象信息
     */
    @Override
    public SysUser selectUserByUserName(String userName) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("user_name", userName);
        return userMapper.selectOne(queryWrapper);
    }

    /**
     * 通过用户ID查询用户
     *
     * @param userId 用户ID
     * @return 用户对象信息
     */
    @Override
    public SysUser selectUserById(Long userId) {
        return userMapper.selectById(userId);
    }

    /**
     * 查询用户所属角色组
     *
     * @param user 用户名
     * @return 结果
     */
    @Override
    public String selectUserRoleGroup(SysUser user) {
        List<SysRole> list = roleService.selectRoleListByUserId(user.getUserId());
        StringBuffer idsStr = new StringBuffer();
        for (SysRole role : list) {
            idsStr.append(role.getRoleName()).append(",");
        }
        if (StringUtils.isNotEmpty(idsStr.toString())) {
            return idsStr.substring(0, idsStr.length() - 1);
        }
        return idsStr.toString();
    }

    /**
     * 查询用户所属岗位组
     *
     * @param user 用户名
     * @return 结果
     */
    @Override
    public String selectUserPostGroup(SysUser user) {
        List<SysPost> list = postService.selectPostsByUserId(user.getUserId());
        StringBuffer idsStr = new StringBuffer();
        for (SysPost post : list) {
            idsStr.append(post.getPostName()).append(",");
        }
        if (StringUtils.isNotEmpty(idsStr.toString())) {
            return idsStr.substring(0, idsStr.length() - 1);
        }
        return idsStr.toString();
    }

    /**
     * 校验用户名称是否唯一
     *
     * @param user 用户
     * @return 结果
     */
    @Override
    public boolean checkUserNameUnique(SysUser user) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("user_name", user.getUserName());
        queryWrapper.ne(ObjectUtil.isNotEmpty(user.getUserId()), "user_id", user.getUserId());
        return userMapper.selectCount(queryWrapper) == 0;
    }

    /**
     * 校验用户是否允许操作
     *
     * @param user 用户信息
     */
    @Override
    public void checkUserAllowed(SysUser user) {
        if (StringUtils.isNotNull(user.getUserId()) && SecurityUtils.isAdmin(user.getUserId()) && !SecurityUtils.isAdmin()) {
            throw new CustomException("不允许操作超级管理员用户");
        }
    }

    /**
     * 新增用户信息
     *
     * @param user 用户信息
     * @return 结果
     */
    @Override
    @Transactional
    public int insertUser(SysUser user) {
        user.setCreateBy(SecurityUtils.getUsername());
        user.setCreateTime(new Date());
        user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
        // 新增用户信息
        int rows = userMapper.insert(user);
        // 新增用户岗位关联
        insertUserPost(user);
        // 新增用户与角色管理
        insertUserRole(user);
        return rows;
    }

    /**
     * 修改用户信息
     *
     * @param user 用户信息
     * @return 结果
     */
    @Override
    @Transactional
    public int updateUser(SysUser user) {
        Long userId = user.getUserId();
        // 删除用户与角色关联
        deleteUserRoleByUserId(userId);
        // 新增用户与角色管理
        insertUserRole(user);
        // 删除用户与岗位关联
        deleteUserPostByUserId(userId);
        // 新增用户与岗位管理
        insertUserPost(user);
        user.setPassword(null);
        user.setUpdateBy(SecurityUtils.getUsername());
        user.setUpdateTime(new Date());
        return userMapper.updateById(user);
    }

    private void deleteUserRoleByUserId(Long userId) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("user_id", userId);
        userRoleMapper.delete(queryWrapper);
    }

    private void deleteUserPostByUserId(Long userId) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("user_id", userId);
        userPostMapper.delete(queryWrapper);
    }

    /**
     * 修改用户状态
     *
     * @param user 用户信息
     * @return 结果
     */
    @Override
    public int updateUserStatus(SysUser user) {
        return userMapper.updateById(user);
    }

    /**
     * 修改用户基本信息
     *
     * @param user 用户信息
     * @return 结果
     */
    @Override
    public int updateUserProfile(SysUser user) {
        return userMapper.updateById(user);
    }

    /**
     * 修改用户头像
     *
     * @param userName 用户名
     * @param avatar   头像地址
     * @return 结果
     */
    @Override
    public boolean updateUserAvatar(String userName, String avatar) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("user_name", userName);
        SysUser user = new SysUser();
        user.setAvatar(avatar);
        return userMapper.update(user, queryWrapper) > 0;
    }

    /**
     * 重置用户密码
     *
     * @param user 用户信息
     * @return 结果
     */
    @Override
    public int resetPwd(SysUser user) {
        return userMapper.updateById(user);
    }

    /**
     * 重置用户密码
     *
     * @param userName 用户名
     * @param password 密码
     * @return 结果
     */
    @Override
    public boolean resetUserPwd(String userName, String password) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("user_name", userName);
        SysUser user = new SysUser();
        user.setPassword(password);
        return userMapper.update(user, queryWrapper) > 0;
    }

    /**
     * 新增用户角色信息
     *
     * @param user 用户对象
     */
    public void insertUserRole(SysUser user) {
        Long[] roles = user.getRoleIds();
        if (StringUtils.isNotNull(roles)) {
            // 新增用户与角色管理
            List<SysUserRole> list = new ArrayList<SysUserRole>();
            for (Long roleId : roles) {
                SysUserRole ur = new SysUserRole();
                ur.setUserId(user.getUserId());
                ur.setRoleId(roleId);
                list.add(ur);
            }
            if (list.size() > 0) {
                userRoleMapper.batchUserRole(list);
            }
        }
    }

    /**
     * 新增用户岗位信息
     *
     * @param user 用户对象
     */
    public void insertUserPost(SysUser user) {
        Long[] posts = user.getPostIds();
        if (StringUtils.isNotNull(posts)) {
            // 新增用户与岗位管理
            List<SysUserPost> list = new ArrayList<SysUserPost>();
            for (Long postId : posts) {
                SysUserPost up = new SysUserPost();
                up.setUserId(user.getUserId());
                up.setPostId(postId);
                list.add(up);
            }
            if (list.size() > 0) {
                userPostMapper.batchUserPost(list);
            }
        }
    }

    /**
     * 通过用户ID删除用户
     *
     * @param userId 用户ID
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteUserById(Long userId) {
        // 删除用户与角色关联
        deleteUserRoleByUserId(userId);
        // 删除用户与岗位表
        deleteUserPostByUserId(userId);
        return userMapper.deleteById(userId);
    }

    /**
     * 批量删除用户信息
     *
     * @param userIds 需要删除的用户ID
     * @return 结果
     */
    @Override
    public int deleteUserByIds(Long[] userIds) {
        for (Long userId : userIds) {
            checkUserAllowed(new SysUser(userId));
        }
        if (userIds.length == 0) return 0;
        return userMapper.deleteBatchIds(ListUtil.toList(userIds));
    }
}
